<?php
namespace app\controller;
use Rtgm\sm\RtSm2;
/**
 * 订单支付
 */
class Juhe extends Base
{
    protected $noAuth = ['index'];
    private $sm_userId = '1234567812345678';
    private $appid = '8ab74856-8772-45c9-96db-54cb30ab9f74';//测试用
    private $secrt='5b96f20a-011f-4254-8be8-9a5ceb2f317f';
    
    //商户私钥（商户端联调测试加签使用）：
    private $key = 'D5F2AFA24E6BA9071B54A8C9AD735F9A1DE9C4657FA386C09B592694BC118B38';
    //招行公钥（商户端联调测试验签使用）：
    private $pub_key='MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE6Q+fktsnY9OFP+LpSR5Udbxf5zHCFO0PmOKlFNTxDIGl8jsPbbB/9ET23NV+acSz4FEkzD74sW2iiNVHRLiKHg==';
    private $t_start="3059301306072a8648ce3d020106082a811ccf5501822d03420004";//公钥头
    
    private $merId = '请使用您自己的';//商户号
    private $version = "0.0.1";//版本号
    private $encoding = "UTF-8";//编码方式,固定为UTF-8
    private $signMethod = "02";//"02：签名方法为SM2";//
   
    //回调地址
    private $notifyUrl = '请使用您自己的';
    private $appurl= 'https://api.cmburl.cn:8065/polypay/v1.0/mchorders/';//测试
    //private $appurl= 'https://api.cmbchina.com/polypay/v1.0/mchorders/';//正式
    private $currencyCode = '156';//默认156，目前只支持人民币（156）
    private $tradeScene = 'OFFLINE';//:线下' INSURANCE：保险 CHARITY：公益'
    //生成收款二维码
    public function index(){
        $data=array();
        $data['orderId']="test".time();
        $data['amount']=0.01;
        echo json_encode($this->paycode($data));
    }
    private function paycode($data){
        $params = array();
        $biz_content=array();
        $biz_content["orderId"] = $data['orderId'];
        $biz_content["notifyUrl"] = $this->notifyUrl;
        $biz_content["merId"] = $this->merId;
        $biz_content["payValidTime"] = !empty($data['payValidTime'])?$data['payValidTime']:900;
        $biz_content["currencyCode"]=$this->currencyCode;
        //$biz_content["userId"] = $this->userId;
        $biz_content["txnAmt"] = ceil($data['amount']*100);//单位分
        $biz_content["mchReserved"]="备注";
        $biz_content["body"] = '在线支付';
        $biz_content["tradeScene"] = $this->tradeScene;
        
        $params["encoding"] = $this->encoding;
        $params["version"] = $this->version;
        $params["signMethod"] = $this->signMethod;
        //$params["appid"] = $this->appid;
        $biz_content = array_filter($biz_content);
        ksort($biz_content);
        $params["biz_content"]=json_encode($biz_content);
        //签名
        $params = array_filter($params);
        ksort($params);
        $sign = $this->Sign($params);//签名
        $params["sign"] = $sign;
        ksort($params);
        //
        $url = $this->appurl."qrcodeapply";
        $header=$this->get_header_arr($sign);
        $pay=$this->curl_post($url,$params,$header);
        
        $pay=json_decode($pay,true);
        
        if($this->validSign($pay)){
            //返回支付的二维码的code值
            return $pay;
        }
    }
    /*
    按照招行聚合支付文档对appid进行加签生成请求头
    */
    private function get_header_arr($sign){
        $header = array("Content-Type: application/json;charset=UTF-8","Accept:application/json");
        $params=array();
        $params["appid"] = $this->appid;
        $params["secret"] = $this->secrt;
        $params["sign"] = $sign;
        $params["timestamp"] = time();
        $params = array_filter($params);
        ksort($params);
        $document = $this->ToUrlParams($params);
        $apisign=md5($document);
        $header[]="appid:".$params['appid'];
        $header[]='timestamp:'.$params['timestamp'];
        $header[]='apisign:'.$apisign;
        return $header;
    }
   
    /**
     * @name unknown curl请求
     * @param unknown $data 请求参数
     * @param unknown $url 请求地址
     * @param number $header 报文头
     * @return shihandong
     */
    public function curl_post($url,$params,$header){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER,1);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt ($curl, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
        if(!empty($header)){
            curl_setopt ( $curl, CURLOPT_HTTPHEADER, $header );
        }
        
        if(is_array($params)){
            $params = json_encode($params);
        }
        curl_setopt($curl, CURLOPT_POSTFIELDS,$params);
        
        $data = curl_exec($curl);
        $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);//关闭cURL会话
        return $data;
    }
    public  function ToUrlParams(array $array){
        $buff = "";
        foreach ($array as $k => $v)
        {
            if($v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }
    
    
    //SM2 签名
    private function Sign(array $array){
        $array = array_filter($array);
        ksort($array);//整理数组排序
        $document = $this->ToUrlParams($array);//拼接
        //加签
        $sm2 = new RtSm2('base64');
        $sign = $sm2->doSign( $document,$this->key , $this->sm_userId);
        return $sign;
    }
    
    
    /**
     * 校验签名
     */
    private function ValidSign(array $array){
        $sign =$array['sign'];
        unset($array['sign']);
        ksort($array);
        $document = $this->ToUrlParams($array);
        $sm2 = new RtSm2('base64');
        
        $bstr=base64_decode($this->pub_key);//base64解码公钥
        $pk=bin2hex($bstr);//转16进制
        //去公钥头
        $pkarr=explode($this->t_start,$pk);
        $pubkey=$pkarr[1];//实际公钥
        return $sm2->verifySign( $document, $sign, $pubkey,  $this->sm_userId);
    }
}